package com.muse.sentinel.demo2.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.muse.sentinel.demo2.exception.ExceptionUtil;
import com.muse.sentinel.demo2.service.SentinelWithAnnotationService;

@Service
public class SentinelWithAnnotationServiceImpl implements SentinelWithAnnotationService {
    /** 业务处理逻辑 */
    @SentinelResource(value = FLOW_RULES_RESOURCES_PROCESS, blockHandler = "processBlockHandler",
            fallback = "fallbackHandler")
    public void process() {
        System.out.println("process run!");
        /*您的业务逻辑*/
        try {
            Thread.sleep(40);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /** Block异常处理函数，参数最后多一个BlockException，其余与原函数一致 */
    public void processBlockHandler(BlockException e) {
        System.out.println("block!");
    }
    /** Fallback函数，函数签名与原函数一致或加一个Throwable类型的参数 */
    public void fallbackHandler() {
        System.out.println("fallback!");
    }


    /**
     * 这里单独演示blockHandlerClass的配置
     * blockHandler：表示对应的方法名，并且必须为public static修饰的函数.
     * blockHandlerClass：表示对应的blockHandler处理类，
     */
    @SentinelResource(value = FLOW_RULES_RESOURCES_PROCESS_1, blockHandler = "processBlockHandler",
            blockHandlerClass = {ExceptionUtil.class})
    public void process1() {
        System.out.println("process1 run!");
    }

    /** 配置限流策略 */
    public void initFlowRules(String resource) {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource(resource);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(20); // Set limit QPS to 20.
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}
